/*
 * Copyright (C) 2010-2012 Enrique Lara (enrique.posix2.lara@gmail.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package trs.wmata;

import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;

import android.database.Cursor;

import android.net.Uri;

import android.text.TextUtils;

import app.transitalarm.Android;
import app.transitalarm.R;

import app.transitalarm.model.Agency;
import app.transitalarm.model.Alarm;
import app.transitalarm.model.App;
import app.transitalarm.model.DataRetrievalException;
import app.transitalarm.model.Route;
import app.transitalarm.model.Stop;
import app.transitalarm.model.Vehicle;

import app.transitalarm.provider.Tables.Alarms;

import app.transitalarm.util.Constants;
import app.transitalarm.util.Log;

import trs.wmata.api.Api;
import trs.wmata.api.NextBus;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Properties;

public final class BusAgency implements Agency {
    public static final int WMATA_BUS_AGENCY_ID = 180;
    private static final String NAME = "METRO-BUS";
    private static final String URL = "http://wwww.wmata.com";
    private static final String TIME_ZONE = "America/New_York";
    private static final String TAG = "BusAgency";
    private final Context context;
    private final Api api;

    public static BusAgency getInstance(final Context context) {
        return new BusAgency(context);
    }

    BusAgency(final Context context) {
        this.context = context;

        final Properties config = App.getConfig(context);
        api = new Api(context, this, config.getProperty("wmata.api.baseUrl"), config.getProperty("wmata.api.key"));
    }

    @Override
    public ArrayList<Vehicle> getVehicles(final Stop station) throws DataRetrievalException {
        return getVehicles(station.getCode());
    }

    @Override
    public ArrayList<Vehicle> getVehicles(final String stopCode) throws DataRetrievalException {
        final NextBus stopPrediction = api.getNextBus(stopCode);

        final ArrayList<Bus> buses = stopPrediction.getBuses();
        final ArrayList<Vehicle> rval = new ArrayList<Vehicle>(buses.size());
        rval.addAll(buses);

        return rval;
    }

    @Override
    public Stop getStopByCode(final String apiCode) throws DataRetrievalException {
        return api.getBusStopSchedule(apiCode).getBusStop();
    }

    @Override
    public Route getRouteByCode(final String routeCode) {
        if (TextUtils.isEmpty(routeCode)) {
            return BusRoute.UNKNOWN_ROUTE;
        }

        return new BusRoute(routeCode, api);
    }

    @Override
    public String[] getRouteNames() {
        return new String[] {
                   "UKNOWN"
               }; //XXX optional? or getRoutes()..
    }

    @Override
    public String[] getRouteCodes() {
        return new String[] {
                   "UKNOWN"
               }; //XXX optional?
    }

    @Override
    public String[] getStopNames(final String line) {
        return new String[] {
                   "UKNOWN"
               }; //XXX optional?
    }

    @Override
    public String[] getStopCodes(final String line) {
        return new String[] {
                   "UKNOWN"
               }; //XXX optional? getStopsForRoute
    }

    @Override
    public boolean gotoViewStop(final String apiCode, final Uri uri) {
        Stop station = null;

        try {
            station = this.getStopByCode(apiCode);
        } catch (final DataRetrievalException e) {
            Log.w(TAG, "Could not locate stop: " + apiCode, e);
        }

        if (station == null) {
            Android.showLongToast(context, R.string.could_not_locate_stop, apiCode);

            return false;
        }

        final Intent intent;

        if (uri != null) {
            intent = new Intent(Constants.ACTION_VIEW, uri);
        } else {
            intent = new Intent(Intent.ACTION_VIEW);
            intent.putExtra(Alarms.AGENCY_ID, WMATA_BUS_AGENCY_ID);
            intent.putExtra(Alarms.STOP, station.getCode());
            intent.setType("application/wmata-nextbus");
        }

        context.startActivity(intent);

        return true;
    }

    @Override
    public boolean gotoInsert(final Uri uri) {
        final Intent intent = new Intent(Constants.ACTION_INSERT_STOP_FIRST, uri);
        intent.putExtra(Alarms.AGENCY_ID, WMATA_BUS_AGENCY_ID);
        context.startActivity(intent);

        return true;
    }

    @Override
    public boolean gotoEdit(final Uri uri) {
        context.startActivity(new Intent(Constants.ACTION_EDIT_STOP_FIRST, uri));

        return true;
    }

    @Override
    public String getName() {
        return NAME;
    }

    @Override
    public String getUrl() {
        return URL;
    }

    @Override
    public String getTimeZone() {
        return TIME_ZONE;
    }

    @Override
    public int getPreferenceId() {
        return R.xml.bus_alarm_pref;
    }

    @Override
    public Alarm newAlarm(final Uri uri) {
        final ContentValues values = new ContentValues();

        final Calendar c = Calendar.getInstance();

        values.put(Alarms.AGENCY_ID, WMATA_BUS_AGENCY_ID);
        values.put(Alarms.ENABLED, 0);
        values.put(Alarms.HOUR, c.get(Calendar.HOUR_OF_DAY));
        values.put(Alarms.MINUTE, c.get(Calendar.MINUTE));
        values.put(Alarms.DAYS_IN_WEEK, 0);
        values.put(Alarms.STOP, "1001888");
        values.put(Alarms.ROUTE, "96");
        values.put(Alarms.DIRECTION, "0");
        values.put(Alarms.TIME_MAX, 25);
        values.put(Alarms.TIME_MIN, 10);
        values.put(Alarms.VIBRATE, 1);
        values.put(Alarms.IMAGE, R.drawable.ic_transit_alarm);

        final Uri alarmUri = context.getContentResolver().insert(uri, values);

        if (alarmUri == null) {
            return null;
        }

        return App.loadAlarm(alarmUri, context);
    }

    @Override
    public Alarm loadAlarm(final Cursor cursor, final Context context) {
        return new BusAlarm(cursor, context);
    }

    @Override
    public int getStopListItemViewId() {
        return R.layout.list_item_bus_stop;
    }

    @Override
    public int getStopDividerViewId() {
        return R.layout.list_item_bus_divider;
    }

    @Override
    public int getAlarmListItemViewId() {
        return R.layout.list_item_bus_alarm;
    }

    @Override
    public int getAlarmDialogViewId() {
        return R.layout.alarm_dia_bus;
    }
}
